package main

import (
	"context"
	"fmt"
	"go.etcd.io/etcd/clientv3"
	"go.etcd.io/etcd/mvcc/mvccpb"
	"time"
)

func main() {
	// 配置 + 连接到 etcd client
	var (
		config clientv3.Config  // 客户端配置
		client *clientv3.Client // 客户端
		err error
		kv clientv3.KV          // kv客户端
		putResp *clientv3.PutResponse
		delResp *clientv3.DeleteResponse
		getResp *clientv3.GetResponse
		watchStartRevision int64 // 监听版本开始位置
		watcher clientv3.Watcher // 监听器
		watcherRespChan <- chan clientv3.WatchResponse
		watcherResp clientv3.WatchResponse
		event *clientv3.Event

	)

	// 配置
	config = clientv3.Config{
		Endpoints:[]string{"127.0.0.1:2379"},
		DialTimeout:5*time.Second,
	}

	// 连接客户端
	if client,err = clientv3.New(config);err != nil{
		fmt.Println(err)
		return
	}

	kv = clientv3.NewKV(client)

	go func() {
		for {
			// put
			putResp,err = kv.Put(context.TODO(),"/cron/jobs/job6","hello");

			// delete
			delResp,err = kv.Delete(context.TODO(),"/cron/jobs/job6")

			time.Sleep(2*time.Second)
		}
	}()

	// get 获取一个版本，用以监听该版本以后的变化
	if getResp,err = kv.Get(context.TODO(),"/cron/jobs/job6");err != nil {
		fmt.Println(err)
	}

	if len(getResp.Kvs) !=0 {
		fmt.Println("当前值",string(getResp.Kvs[0].Value))
	}

	// 启动监听器
	watcher = clientv3.NewWatcher(client)

	// 监听 key 后续变化
	watchStartRevision = getResp.Header.Revision+1
	fmt.Println("从版本",watchStartRevision,"开始向后监听")

	// 启动5秒的上下文管理器
	ctx,cancelFunc := context.WithCancel(context.TODO())
	time.AfterFunc(5*time.Second,func() {
		cancelFunc()
	})

	// 默认一直运行，添加一个5秒的上下文，以关闭chan
	watcherRespChan = watcher.Watch(ctx,"/cron/jobs/job6",clientv3.WithRev(watchStartRevision))

	// 处理变化
	for watcherResp = range watcherRespChan{
		for _,event = range watcherResp.Events {
			switch event.Type {
			case mvccpb.PUT:
				fmt.Println("value修改为:",string(event.Kv.Value),"CreateRevision:",event.Kv.CreateRevision,"ModRevision:",event.Kv.ModRevision)
			case mvccpb.DELETE:
				fmt.Println("删除了，修改版本号为",event.Kv.ModRevision)

			}
		}
	}

}
